#pragma once

#include <string>
#include <cstring>
#include <iostream>
#include "Log.hpp"
#include <jsoncpp/json/json.h>

const std::string SEP = " ";
const size_t SEP_LEN = SEP.size();
const std::string LINE_SKIP = "\r\n";
const size_t LINE_SKIP_LEN = LINE_SKIP.size();

enum
{
    DIV_ERRO = 1,
    MOD_ERRO,
    OPERA_ERRO
};

//"x op y" -> lenth\\r\\n"x op y"\\r\\n
// 添加报头
const std::string enLenth(const std::string &masg)
{
    std::string response = std::to_string(masg.size());
    response += (LINE_SKIP + masg + LINE_SKIP);
    return response;
}

/* lenth\r\n"x op y"\r\n -> "x op y"
去除报头*/
bool deLenth(const std::string &package, std::string *out)
{
    logMessage(DEBUG, "deLenth in ...");
    auto pos = package.find(LINE_SKIP);
    if (pos == std::string::npos)
        return false;

    int masg_lenth = std::stoi(package.substr(0, pos));

    *out = package.substr(pos + LINE_SKIP_LEN, masg_lenth);

    logMessage(DEBUG, "deLenth out ...");

    return true;
}

// 接收请求字节流
bool recvPackge(std::string &inbuffer, std::string *outbuffer)
{
    logMessage(DEBUG, "recvPackge in ...");
    *outbuffer = "";
    // lenth\r\n"x op y"\r\n -> "x op y"
    auto len = inbuffer.find(LINE_SKIP);
    if (len == std::string::npos)
    {
        return false;
    }

    std::cout << "len: " << len << std::endl;

    std::string str_text_len = inbuffer.substr(0, len);

    logMessage(DEBUG, "str_text_len:%s....", str_text_len.c_str());

    int text_len = std::stoi(str_text_len);

    logMessage(DEBUG, "str_text_len:%d....", text_len);

    int total_len = text_len + 2 * LINE_SKIP_LEN + str_text_len.size();

    if (inbuffer.size() < total_len)
    {
        logMessage(ERROR, "协议格式错误");
        return false;
    }

    *outbuffer = inbuffer.substr(0, total_len);
    inbuffer.erase(0, total_len);

    logMessage(DEBUG, "recvPackge out ...");

    return true;
}

class Request
{
public:
    Request()
        : _x(0), _y(0), _op(0)
    {
    }
    Request(int x, int y, char op)
        : _x(x), _y(y), _op(op)
    {
    }

    //"x op y"
    // 取内容
    bool serialize(std::string *out)
    {

        Json::Value root;

        root["x"] = _x;
        root["y"] = _y;
        root["operator"] = _op;

        Json::FastWriter writer;
        // Json::StyledWriter writer;
        *out = writer.write(root);

        return true;
    }

    // 反序列化：将内容切割
    bool deserialize(const std::string &in)
    {
        Json::Value root;
        Json::Reader read;

        read.parse(in, root);
        _x = root["x"].asInt();
        _y = root["y"].asInt();
        _op = root["operator"].asInt();

        return true;
    }

public:
    int _x;
    int _y;
    char _op;
};

class Response
{
public:
    Response()
        : _exitcode(0), _result(0)
    {
    }

    // "exitcode result"
    bool serialize(std::string *out)
    {
        Json::Value root;
        root["exitcode"] = _exitcode;
        root["result"] = _result;

        Json::FastWriter writer;
        *out = writer.write(root);

        return true;
    }

    bool deserialize(const std::string &in)
    {

        Json::Value root;
        Json::Reader read;

        read.parse(in, root);

        _exitcode = root["exitcode"].asInt();
        _result = root["result"].asInt();

        return true;
    }

public:
    int _exitcode;
    int _result;
};